package com.hemerasolutions.v2trainer.model.base;

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import javax.persistence.Column;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;

import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import com.hemerasolutions.v2trainer.model.unit.volume.VolumeFactor;

@MappedSuperclass
public class BaseValueRangeHolder extends BaseModel {

	private static final long serialVersionUID = 1L;

    @Column
	protected double lowValue;
	 
    @Column	
	protected double highValue;

    @ManyToOne
    protected VolumeFactor volumeFactor;
    
    public BaseValueRangeHolder(){
    	super();
		this.lowValue = 0;
		this.highValue = 0;
    }
    
	public double getLowValue() {
		if(this.volumeFactor != null && lowValue != 0 ){
			EvaluationContext context 	= new StandardEvaluationContext(); 
			ExpressionParser parser 	= new SpelExpressionParser();
			Expression exp = null;

		
			context.setVariable("value", lowValue);
			exp = parser.parseExpression( this.volumeFactor.getUpFormula());
			
			return (double) exp.getValue(context);
		}else{
			return lowValue ;
			
		}
	}

	public void setLowValue(double lowValue) {
		if(this.volumeFactor != null && lowValue != 0 ){
			EvaluationContext context 	= new StandardEvaluationContext(); 
			ExpressionParser parser 	= new SpelExpressionParser();
			Expression exp = null;
			 
			context.setVariable("value", lowValue);
			exp = parser.parseExpression( this.volumeFactor.getDownFormula());
			
			this.lowValue = (double) exp.getValue(context);			
		}else{
			this.lowValue = lowValue  ;
		}

	}	
	


	public Date getLowDateValue() {

		Calendar c = Calendar.getInstance();
		c.setTimeZone(TimeZone.getTimeZone("Etc/GMT0"));

		if(lowValue != 0){
			c.setTimeInMillis((long)this.getLowValue()*1000);
		}else{
			c.setTimeInMillis(0);
		}

		return c.getTime();
	}

	public void setLowDateValue(Date lowDateValue) {

		Calendar c = Calendar.getInstance();
		c.setTimeZone(TimeZone.getTimeZone("Etc/GMT0"));

		if(lowDateValue != null){
			c.setTime(lowDateValue);
			if(c.getTimeInMillis() == 0){
				this.lowValue = 0;
			}else{
				this.setLowValue((double)c.getTimeInMillis()/1000);
			}
		}else{
			this.lowValue = 0;
		}

	}

	public double getHighValue() {
		if(this.volumeFactor != null && this.highValue != 0){
			EvaluationContext context 	= new StandardEvaluationContext(); 
			ExpressionParser parser 	= new SpelExpressionParser();
			Expression exp = null;
			 
			context.setVariable("value", this.highValue);
			exp = parser.parseExpression( this.volumeFactor.getUpFormula() );

			return (double) exp.getValue(context);
		}else{
			return highValue ;
		}
	}

	public void setHighValue(double highValue) {
		if(this.volumeFactor != null && highValue != 0){
			EvaluationContext context 	= new StandardEvaluationContext(); 
			ExpressionParser parser 	= new SpelExpressionParser();
			Expression exp = null;
			 
			context.setVariable("value", highValue);
			exp = parser.parseExpression( this.volumeFactor.getDownFormula() );
			
			this.highValue = (double) exp.getValue(context);			
		}else{
			this.highValue = highValue  ;
		}
	}		
	
	public Date getHighDateValue() {

		Calendar c = Calendar.getInstance();
		c.setTimeZone(TimeZone.getTimeZone("Etc/GMT0"));

		if(highValue != 0){
			c.setTimeInMillis((long)this.getHighValue()*1000);
		}else{
			c.setTimeInMillis(0);
		}

		return c.getTime();
	}

	public void setHighDateValue(Date highDateValue) {

		Calendar c = Calendar.getInstance();
		c.setTimeZone(TimeZone.getTimeZone("Etc/GMT0"));

		if(highDateValue != null){
			c.setTime(highDateValue);
			if(c.getTimeInMillis() == 0){
				this.highValue = 0;
			}else{
				this.setHighValue((double)c.getTimeInMillis()/1000);
			}
		}else{
			this.highValue = 0;
		}

	}

	public VolumeFactor getVolumeFactor() {
		return volumeFactor;
	}

	public void setVolumeFactor(VolumeFactor volumeFactor) {
		this.volumeFactor = volumeFactor;
	}

    

}
